#include <Wire.h>
#include <Adafruit_INA219.h>
#include <U8g2lib.h>

// 引脚定义（ESP32-DevKitC）
#define INA219_SDA 15  // INA219的SDA连接到GPIO15
#define INA219_SCL 14  // INA219的SCL连接到GPIO14
#define OLED_SDA  5    // OLED的SDA连接到GPIO5
#define OLED_SCL  4    // OLED的SCL连接到GPIO4
#define SCREEN_WIDTH 128  // OLED显示宽度（像素）
#define SCREEN_HEIGHT 64  // OLED显示高度（像素）
#define OLED_RESET    -1  // 重置引脚（没有则设为-1）

// 创建传感器和显示屏对象
Adafruit_INA219 ina219;
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, OLED_SCL, OLED_SDA, U8X8_PIN_NONE);

// 锂电池参数
const float MAX_BATTERY_VOLTAGE = 4.2;
const float MIN_BATTERY_VOLTAGE = 3.0;

// 滑动平均滤波参数
#define FILTER_SIZE 5
float voltageBuffer[FILTER_SIZE];
int bufferIndex = 0;

// 锂电池电压-电量非线性映射表
float calculateBatteryPercentage(float voltage) {
  if (voltage >= 4.18) return 100;  // 接近满电
  if (voltage >= 4.0)  return 90;   // 高电量
  if (voltage >= 3.85) return 75;   // 典型使用区间
  if (voltage >= 3.75) return 60;   // 中高电量
  if (voltage >= 3.65) return 40;   // 中等电量
  if (voltage >= 3.55) return 25;   // 低电量
  if (voltage >= 3.4)  return 10;   // 极低电量
  return 0;                         // 放空
}

// 电压滤波函数
float filterVoltage(float newVoltage) {
  voltageBuffer[bufferIndex++] = newVoltage;
  if (bufferIndex >= FILTER_SIZE) bufferIndex = 0;
  
  float sum = 0;
  for (int i = 0; i < FILTER_SIZE; i++) {
    sum += voltageBuffer[i];
  }
  return sum / FILTER_SIZE;
}

void setup() {
  Serial.begin(115200);
  Wire.begin(INA219_SDA, INA219_SCL);
  
  // 初始化滤波缓冲区
  for (int i = 0; i < FILTER_SIZE; i++) {
    voltageBuffer[i] = 0;
  }
  
  // 初始化INA219
  if (!ina219.begin()) {
    Serial.println("INA219初始化失败!");
    while (1);
  }
  ina219.setCalibration_32V_2A();
  Serial.println("INA219初始化成功!");
  
  // 删除或注释掉充电检测引脚初始化
  // pinMode(CHARGE_PIN, INPUT_PULLUP);
  
  // 初始化OLED
  u8g2.begin();
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.setCursor(0, 10);
  u8g2.print("锂电池监测系统");
  u8g2.sendBuffer();
  delay(1000);
}

void loop() {
  // 读取原始数据
  float rawVoltage = ina219.getBusVoltage_V();
  float current = ina219.getCurrent_mA();
  float walt = ina219.getPower_mW();
  // 删除或注释掉充电检测逻辑
  // bool isCharging = digitalRead(CHARGE_PIN) == LOW;
  
  // 滤波处理
  float filteredVoltage = filterVoltage(rawVoltage);
  
  // 计算电量百分比（移除充电状态判断）
  float batteryPercentage = calculateBatteryPercentage(filteredVoltage);
  
  // 串口调试输出
  Serial.print("原始电压: "); Serial.print(rawVoltage, 2); Serial.println(" V");
  Serial.print("滤波电压: "); Serial.print(filteredVoltage, 2); Serial.println(" V");
  Serial.print("电流: "); Serial.print(current, 1); Serial.println(" mA");
  Serial.print("功率: "); Serial.print(walt, 3); Serial.println(" mW");
  
  Serial.print("映射区间: ");
  if (filteredVoltage >= 4.18) Serial.println("100% (>=4.18V)");
  else if (filteredVoltage >= 4.0) Serial.println("90% (4.0-4.18V)");
  else if (filteredVoltage >= 3.85) Serial.println("75% (3.85-4.0V)");
  else if (filteredVoltage >= 3.75) Serial.println("60% (3.75-3.85V)");
  else if (filteredVoltage >= 3.65) Serial.println("40% (3.65-3.75V)");
  else if (filteredVoltage >= 3.55) Serial.println("25% (3.55-3.65V)");
  else if (filteredVoltage >= 3.4) Serial.println("10% (3.4-3.55V)");
  else Serial.println("0% (<3.4V)");
  
  Serial.print("计算电量: "); Serial.print(batteryPercentage, 0); Serial.println(" %");
  Serial.println("------------------");
  
  // OLED显示
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr);
  
  // 功率显示
  u8g2.setCursor(0, 0);
  u8g2.print("Walt: ");
  u8g2.print(walt, 2);
  u8g2.print(" mW");

  // 电压显示
  u8g2.setCursor(0, 12);
  u8g2.print("Voltage: ");
  u8g2.print(filteredVoltage, 2);
  u8g2.print(" V");
  
  // 电流显示
  u8g2.setCursor(0, 26);
  u8g2.print("Current: ");
  u8g2.print(current, 1);
  u8g2.print(" mA");
  
  // 电量显示
  u8g2.setCursor(0, 40);
  u8g2.print("Battery: ");
  u8g2.print(batteryPercentage, 0);
  u8g2.print(" %");
  
  // 进度条绘制
  u8g2.drawFrame(0, 45, 128, 15);
  int progressWidth = (batteryPercentage / 100.0) * 124;
  u8g2.drawBox(2, 47, progressWidth, 11);
  
  u8g2.sendBuffer();
  delay(1000);
}